package org.nlp2rdf.navigator.client;

import java.util.LinkedHashMap;
import java.util.Map;

import org.nlp2rdf.navigator.client.common.ClassificationCountResultDTO;
import org.nlp2rdf.navigator.client.common.ClassificationResultDTO;
import org.nlp2rdf.navigator.client.common.ExampleDTO;
import org.nlp2rdf.navigator.client.common.LearnedConceptDTO;
import org.nlp2rdf.navigator.client.functionality.ExampleWidget;
import org.nlp2rdf.navigator.client.functionality.PaginationWidget;
import org.nlp2rdf.navigator.client.functionality.TitleWidget;
import org.nlp2rdf.navigator.client.functionality.Tooltip;
import org.nlp2rdf.navigator.client.util.ConceptDTOHelper;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;

public class ClassifiedInstancesWidget extends Composite {

	// private List<ExampleDTO> retrievedExamples = new ArrayList<ExampleDTO>();
	private Map<String, ExampleDTO> retrievedExamples = new LinkedHashMap<String, ExampleDTO>();

	private Application app;

	private Button countButton = new Button("count instances");
	private Label resultCount = new Label("(no Results)");
	private FlowPanel tooltipForConcept = new FlowPanel();

	private LearnedConceptDTO learningResult;

	PaginationWidget paginationWidget = new PaginationWidget(50) {
		@Override
		protected void _paginate() {
			app.getWorkerService().classify(learningResult.getKbSyntaxString(), this.increment, this.current,
					new AsyncCallback<ClassificationResultDTO>() {
						public void onSuccess(ClassificationResultDTO c) {
							updateIndex(c.getRetrievedExamples().size());
							update(c);
						}

						public void onFailure(Throwable arg0) {
							app.reportError(arg0);
						}
					});
		}
	};

	final private VerticalPanel retrievedExamplesTable = new VerticalPanel();
	final private TitleWidget titleWidget = new TitleWidget("Classified Instances", retrievedExamplesTable,
			paginationWidget);

	public ClassifiedInstancesWidget(final Application app) {
		this.app = app;

		tooltipForConcept.add(new Label("Current concept: none"));
		VerticalPanel mainPanel = new VerticalPanel();

		/*
		 * The TOP *
		 */
		Tooltip.assignToolTip(titleWidget.getTitelLabel(), tooltipForConcept);

		countButton.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent arg0) {
				disableCountButton();

				app.getWorkerService().classifyCount(learningResult.getKbSyntaxString(),
						new AsyncCallback<ClassificationCountResultDTO>() {

							public void onSuccess(ClassificationCountResultDTO classcount) {
								resultCount.setText(Integer.toString(classcount.getCount()) + " instances");
								resultCount.setVisible(true);
								countButton.setVisible(false);
							}

							public void onFailure(Throwable arg0) {
								app.reportError(arg0);
								enableCountButton();

							}
						});

			}
		});

		titleWidget.getTop().add(countButton);
		titleWidget.getTop().add(resultCount);
		titleWidget.getTop().setCellHorizontalAlignment(titleWidget.getTitelLabel(),
				HasHorizontalAlignment.ALIGN_LEFT);
		titleWidget.getTop().setCellHorizontalAlignment(countButton, HasHorizontalAlignment.ALIGN_RIGHT);
		titleWidget.getTop().setCellHorizontalAlignment(resultCount, HasHorizontalAlignment.ALIGN_RIGHT);

		titleWidget.getBottom().add(paginationWidget);
		titleWidget.getBottom().setCellHorizontalAlignment(countButton, HasHorizontalAlignment.ALIGN_RIGHT);

		mainPanel.add(titleWidget.getTop());
		mainPanel.add(titleWidget.getBottom());

		retrievedExamplesTable.setVisible(false);
		paginationWidget.setVisible(false);
		countButton.setVisible(false);
		resultCount.setVisible(false);

		mainPanel.add(retrievedExamplesTable);
		mainPanel.addStyleName("module-border");
		mainPanel.setWidth("95%");
		mainPanel.addStyleName("greyed");
		draw();
		initWidget(mainPanel);
	}

	private void enableCountButton() {
		countButton.setEnabled(true);
		countButton.setText("count instances");
	}

	private void disableCountButton() {
		countButton.setEnabled(false);
		countButton.setText("counting...");
	}

	private void updateTooltip(LearnedConceptDTO learnedConcept) {
		tooltipForConcept.clear();
		tooltipForConcept.add(new Label("Current concept: "));
		tooltipForConcept.add(ConceptDTOHelper.getHTMLAsFlowPanel(learnedConcept));
	}

	public void collapse(boolean collapse) {
		titleWidget.collapse(collapse);
	}

	// use this for external pushing into
	public void update(ClassificationResultDTO classificationResult, LearnedConceptDTO learnedConcept) {

		this.resultCount.setVisible(false);
		this.countButton.setVisible(true);
		this.retrievedExamplesTable.setVisible(true);
		this.paginationWidget.setVisible(true);

		this.learningResult = learnedConcept;
		updateTooltip(learnedConcept);
		paginationWidget.setCurrent(0);
		paginationWidget.updateIndex(classificationResult.getRetrievedExamples().size());
		enableCountButton();

		update(classificationResult);
	}

	/**
	 * used internally for pagination and update
	 * 
	 * @param classificationResult
	 */
	private void update(ClassificationResultDTO classificationResult) {
		this.retrievedExamples.clear();

		for (ExampleDTO matching : classificationResult.getRetrievedExamples()) {
			if (!app.positiveNegativeWidget.contains(matching)) {
				retrievedExamples.put(matching.getUri(), matching);
			}
		}

		draw();
	}

	private void draw() {
		// flush tables
		retrievedExamplesTable.clear();

		// add content
		ExampleWidget.addExamplesToSelectionTable(app, retrievedExamples, retrievedExamplesTable);

	}

}
